package com.misboot.document.controller;

import cn.hutool.core.convert.Convert;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;


@Controller
@RequestMapping("/erp")
public class iWebOfficeController {

    @Resource
    private MinioController minioController;
    private iMsgServer2015 MsgObj = new iMsgServer2015();
    private static final boolean isWin = System.getProperty("os.name").toLowerCase().contains("win");

    String mOption;
    String mUserName;
    String mRecordID;
    String mFileName;
    String bucket;
    String mCommand;
    String mFilePath; //取得服务器路径
    String mTemplate;

    private static Logger logger = LoggerFactory.getLogger(iWebOfficeController.class);


    @ResponseBody
    @RequestMapping("/officeServer.api")
    public void officeServer(HttpServletRequest request, HttpServletResponse response) {
        mCommand = "";
        //取得服务器路径
        mFilePath = isWin ? "c:\\zuoyo" : "/etc/zuoyo";
        logger.warn("文件存储路径mFilePath{}"+mFilePath);
        String filePath = "";
        try {
            //判断请求方式
            if (request.getMethod().equalsIgnoreCase("POST")) {
                MsgObj.setSendType("JSON");
                //解析请求
                MsgObj.Load(request);
                //请求参数
                mOption = MsgObj.GetMsgByName("OPTION");
                //取得系统用户
                mUserName = MsgObj.GetMsgByName("USERNAME");
                System.out.println(mOption);
                if (mOption.equalsIgnoreCase("LOADFILE")) {
                    //取得文档编号
                    mRecordID = MsgObj.GetMsgByName("RECORDID");
                    logger.warn("文档编号mRecordID{}"+mRecordID);
                    //取得文档名称
                    mFileName = MsgObj.GetMsgByName("FILENAME");
                    logger.warn("文档名称mFileName{}"+mFileName);
                    //取文件地址
                    filePath = MsgObj.GetMsgByName("FILENAME");
                    bucket = MsgObj.GetMsgByName("BUCKET");
                    logger.warn("桶名bucket{}"+bucket);
                    //清除文本信息
                    MsgObj.MsgTextClear();
                    //判断是否指定附件路径还是系统默认路径
                    if (mFileName.indexOf("NPMS") != -1) {
                        if (MsgObj.MsgFileLoad(mFileName)) {
                            //读取文档路径
                            logger.warn(mRecordID + "文档已经加载");
                        }
                    } else {
                        String generateTemporaryUrl = Convert.toStr(minioController.getPresignedObjectUrl(bucket,mFileName,1));
                        saveFile(generateTemporaryUrl, mFilePath, "GET", mFileName);
                        if (MsgObj.MsgFileLoad(mFilePath +"\\"+mFileName)) {   //读取文档路径
                            logger.warn(mRecordID + "文档已经加载");
                        }
                    }
                } else if (mOption.equalsIgnoreCase("SAVEFILE")) {
                    //取得文档编号
                    mRecordID = MsgObj.GetMsgByName("RECORDID");
                    //取得文档名称
                    mFileName = MsgObj.GetMsgByName("FILENAME");
                    //minio桶名
                    bucket = MsgObj.GetMsgByName("BUCKET");

                    logger.warn("桶名bucket{}" + bucket);
                    //清除文本信息
                    MsgObj.MsgTextClear();
                    if (MsgObj.MsgFileSave(mFilePath +"\\"+mFileName)) {
                        logger.warn(mRecordID + "文档已经保存成功");
                        //读取本地文件
                        File fileload = new File(mFilePath +"\\"+mFileName);
                        MultipartFile multipartFile = getMultipartFile(fileload);
                         minioController.uploadfilesdcmNoYYMMdd(multipartFile, bucket, mFileName, mRecordID);
                    }
                }else if (mOption.equalsIgnoreCase("LOADTEMPLATE")) {                  //下面的代码为打开服务器数据库里的模板文件
                    mTemplate = MsgObj.GetMsgByName("TEMPLATE");                        //取得模板文档类型
                    //本段处理是否调用文档时打开模版，还是套用模版时打开模版。
                    MsgObj.MsgTextClear();//清除文本信息
                    if (MsgObj.MsgFileLoad(mFilePath + mTemplate)) { //从服务器文件夹中调入模板文档
                        System.out.println(mTemplate + "文档已经转换成功");                              //清除错误信息
                    }

                }else if (mOption.equalsIgnoreCase("SAVETEMPLATE")) {                  //下面的代码为打开服务器数据库里的模板文件
                    mTemplate = MsgObj.GetMsgByName("TEMPLATE");//取得模板名称
                    System.out.println(mTemplate + "模板上传中");
                    MsgObj.MsgTextClear();//清除文本信息
                    if (MsgObj.MsgFileSave(mFilePath + mTemplate)) {
                        System.out.println(mTemplate + "模板保存成功");
                    }
                } else if (mOption.equalsIgnoreCase("INSERTFILE")) {                  //下面的代码为打开服务器数据库里的模板文件
                    System.out.println("进入INSERTFILE");
                    mTemplate = MsgObj.GetMsgByName("TEMPLATE");//取得模板名称
                    System.out.println(mTemplate + "模板上传中");
                    MsgObj.MsgTextClear();//清除文本信息
                    if (MsgObj.MsgFileLoad(mFilePath + mTemplate)) {
                        System.out.println(mRecordID + "模板保存成功");
                    }
                }
                MsgObj.Send(response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public static MultipartFile getMultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }

        return new CommonsMultipartFile(item);
    }

    /**
     * @param filePath 文件将要保存的目录
     * @param method   请求方法，包括POST和GET
     * @param url      请求的路径
     * @return
     * @从制定URL下载文件并保存到指定目录
     */

    public static File saveFile(String url, String filePath, String method, String fileName) {
        //System.out.println("fileName---->"+filePath);
        //创建不同的文件夹目录
        File file = new File(filePath);
        //判断文件夹是否存在
        if (!file.exists()) {
            //如果文件夹不存在，则创建新的的文件夹
            file.mkdirs();
        }
        FileOutputStream fileOut = null;
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        byte[] buf = new byte[4096];
        try {
            // 建立链接
            URL httpUrl = new URL(url);
            conn = (HttpURLConnection) httpUrl.openConnection();
            //以Post方式提交表单，默认get方式
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            // post方式不能使用缓存
            conn.setUseCaches(false);
            //连接指定的资源
            conn.connect();
            //获取网络输入流
            inputStream = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            //判断文件的保存路径后面是否以/结尾
            if (!filePath.endsWith("/")) {
                filePath += "/";
            }
            //写入到文件（注意文件保存路径的后面一定要加上文件的名称）
            fileOut = new FileOutputStream(filePath + fileName);
            BufferedOutputStream bos = new BufferedOutputStream(fileOut);


            int length = bis.read(buf);
            //保存文件
            while (length != -1) {
                bos.write(buf, 0, length);
                length = bis.read(buf);
            }
            bos.close();
            bis.close();
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("抛出异常！！");
        }

        return file;

    }


    /**
     * @param fileType 文件类型
     * @param method   请求方法，包括POST和GET
     * @param url      请求的路径
     * @return
     * @从制定URL下载文件并保存到指定目录
     */

    public String saveUrlAs(String url, String fileType, String method, String fileName) {
        FileOutputStream fileOut = null;
        HttpURLConnection conn = null;
        InputStream inputStream = null;
        try {
            // 建立链接
            URL httpUrl = new URL(url);
            conn = (HttpURLConnection) httpUrl.openConnection();
            //以Post方式提交表单，默认get方式
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            // post方式不能使用缓存
            conn.setUseCaches(false);
            //连接指定的资源
            conn.connect();
            //获取网络输入流
            inputStream = conn.getInputStream();
            MultipartFile multipartFile = getMultipartFile(inputStream, fileName);
//            HashMap hashMap = minioController.uploadfilesdcmServer(multipartFile, fileType, fileName);丰凯
//            return hashMap.get("filePath").toString();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("抛出异常！！");
        }

        return "";

    }


    /**
     * 获取封装得MultipartFile
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return MultipartFile
     */
    public MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
        FileItem fileItem = createFileItem(inputStream, fileName);
        //CommonsMultipartFile是feign对multipartFile的封装，但是要FileItem类对象
        return new CommonsMultipartFile(fileItem);
    }


    /**
     * FileItem类对象创建
     *
     * @param inputStream inputStream
     * @param fileName    fileName
     * @return FileItem
     */
    public FileItem createFileItem(InputStream inputStream, String fileName) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        String textFieldName = "file";
        FileItem item = factory.createItem(textFieldName, MediaType.MULTIPART_FORM_DATA_VALUE, true, fileName);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        OutputStream os = null;
        //使用输出流输出输入流的字节
        try {
            os = item.getOutputStream();
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            inputStream.close();
        } catch (IOException e) {
            throw new IllegalArgumentException("文件上传失败");
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {

                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                }
            }
        }

        return item;
    }


}
